<template>
  <div id="app">
    <div class="w">
      <el-form label-width="100px">
        <el-form-item
          :required="true"
          label="文章标题"
          :error="article.articleTitle.error"
        >
          <el-input
            v-model="article.articleTitle.value"
            placeholder="请输入文章标题"
            @focus="article.articleTitle.error = ''"
          />
        </el-form-item>
        <el-form-item
          :required="true"
          label="文章描述"
          :error="article.description.error"
        >
          <el-input
            v-model="article.description.value"
            placeholder="请输入文章描述"
            @focus="article.description.error = ''"
          />
        </el-form-item>
        <el-form-item
          :required="true"
          label="文章类型"
        >
          <el-select
            v-model="article.type.value"
          >
            <el-option
              v-for="item in options"
              :key="item.type_id"
              :value="item.type_desc"
            >
              {{item.type_desc}}
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item
          :required="true"
          label="封面图"
          :error="article.cover.error"
        >
          <el-upload
            class="avatar-uploader"
            action="https://r1735185i8.51mypc.cn/api/system/uploadImage"
            name="image"
            :show-file-list="false"
            :headers="{authorization}"
            :on-success="handleAvatarSuccess"
            :before-upload="beforeAvatarUpload"
          >
            <img
              v-if="article.cover.value"
              :src="bindImagePath(article.cover.value)" class="avatar"
            >
            <i v-else class="el-icon-plus avatar-uploader-icon"></i>
          </el-upload>
        </el-form-item>
        <el-form-item
          :required="true"
          label="内容出处"
        >
          <el-radio
            v-model="orgin"
            :label="1">
            原创
          </el-radio>
          <el-radio
            v-model="orgin"
            :label="2"
          >
            转载
          </el-radio>
        </el-form-item>
        <el-form-item
          v-if="orgin === 2"
          :required="true"
          label="转载链接"
          :error="article.orgin.error"
        >
          <el-input
            v-model="article.orgin.value"
            @focus="article.orgin.error = ''"
            placeholder="请输入文章来源或转载链接"
          />
        </el-form-item>
        <el-form-item
          :required="true"
          label="内容"
          :error="article.textContent.error"
        >
          <div style="line-height: normal">
            <quill-editor
              v-model="article.textContent.value"
              ref="quill"
              :options="editorOption"
              @focus="article.textContent.error = ''"
            />
          </div>
        </el-form-item>
        <el-form-item>
          <el-button
            type="primary"
            @click="send"
          >
            发布文章
          </el-button>
        </el-form-item>
      </el-form>
    </div>
    <!---->
    <el-dialog
      title="插入代码"
      :visible.sync="dialogVisible"
    >
      <el-form
        label-width="60px"
      >
        <el-form-item
          label="语言"
          :required="true"
        >
          <el-select
            v-model="dialogData.lang"
          >
            <el-option
              v-for="(item, index) in lang"
              :key="index"
              :value="item"
            >
              {{item}}
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item
          :error="dialogData.contentError"
          label="代码"
          :required="true"
        >
          <el-input
            type="textarea"
            v-model="dialogData.content"
            @focus="dialogData.contentError = ''"
            rows="10"
            placeholder="请输入...."
          />
        </el-form-item>
        <el-form-item>
          <el-button
            type="primary"
            @click="insertCode"
          >
            插入代码
          </el-button>
        </el-form-item>
      </el-form>
    </el-dialog>
  </div>
</template>

<script>
  import $ from 'jquery'
  import Quill from 'quill'
  import { quillEditor } from "vue-quill-editor"
  import 'quill/dist/quill.snow.css'
  import 'highlight.js/styles/a11y-dark.css'

  import highLight from 'highlight.js'
  import JavaScript from 'highlight.js/lib/languages/javascript'
  import CSS from 'highlight.js/lib/languages/css'
  import Json from 'highlight.js/lib/languages/json'
  import XML from 'highlight.js/lib/languages/xml'
  import Java from 'highlight.js/lib/languages/java'
  import Python from 'highlight.js/lib/languages/python'
  import PHP from 'highlight.js/lib/languages/php'
  import ObjectiveC from 'highlight.js/lib/languages/objectivec'
  import Perl from 'highlight.js/lib/languages/perl'

  highLight.registerLanguage('javascript', JavaScript)
  highLight.registerLanguage('css', CSS)
  highLight.registerLanguage('json', Json)
  highLight.registerLanguage('xml', XML)
  highLight.registerLanguage('java', Java)
  highLight.registerLanguage('python', Python)
  highLight.registerLanguage('php', PHP)
  highLight.registerLanguage('objectivec', ObjectiveC)
  highLight.registerLanguage('perl', Perl)

  const BlockEmbed = Quill.import('blots/block/embed')
  const lang = [
    'JavaScript',
    'CSS',
    'HTML',
    'JSON',
    'XML',
    'Java',
    'Python',
    'PHP',
    'Objective-C',
    'Perl',
    'Apache'
  ]

  const toolbarOptions = [
    ['bold', 'italic', 'underline', 'strike'],
    [{ 'list': 'ordered'}, { 'list': 'bullet' }],
    [{ 'indent': '-1'}, { 'indent': '+1' }],
    [{ 'direction': 'rtl' }],

    [{ 'header': [1, 2, 3, 4, 5, 6, false] }],

    [{ 'color': [] }, { 'background': [] }],
    ['image', 'code'],
    [{ 'font': [] }],
    [{ 'align': [] }],

    ['clean']
  ];

  class CodeWrapper extends BlockEmbed {
    static create(value) {
      const node = super.create(value)
      node.innerHTML = value
      return node;
    }
  }
  CodeWrapper.blotName = 'code-wrapper';
  CodeWrapper.tagName = 'div';
  CodeWrapper.className = 'code-wrapper';
  Quill.register(CodeWrapper);

  export default {
    name: 'app',
    components: {
      quillEditor
    },
    watch: {
      orgin (value) {
        if (value === 1) {
          this.article.orgin.value = ''
        }
      }
    },
    data () {
      return {
        lang,
        options: [],
        orgin: 1,
        article: {
          type: {
            error: '',
            value: ''
          },
          cover: {
            error: '',
            value: ''
          },
          orgin: {
            error: '',
            value: ''
          },
          articleTitle: {
            error: '',
            value: ''
          },
          description: {
            error: '',
            value: ''
          },
          textContent: {
            error: '',
            value: ''
          }
        },
        isModify: false,
        dialogData: {
          lang: 'JavaScript',
          content: '',
          contentError: ''
        },
        dialogVisible: false,
        quill: {},
        editorOption: {
          modules: {
            toolbar: toolbarOptions
          }
        },
        authorization: ''
      }
    },
    methods: {
      send () {
        if (!this.article.articleTitle.value) {
          this.article.articleTitle.error = '请输入文章标题！'
        }
        if (!this.article.description.value) {
          this.article.description.error = '请输入文章描述！'
        }
        if (!this.article.cover.value) {
          this.article.cover.error = '请添加文章封面图！'
        }
        if (this.orgin === 2 && !this.article.orgin.value) {
          this.article.orgin.error = '请注明文章来源连接！'
        }
        if (!this.article.textContent.value) {
          this.article.textContent.error = '请输入文章内容！'
        }
        if (
          !!this.article.articleTitle.value &&
          !!this.article.description.value &&
          !!this.article.cover.value &&
          !!this.article.textContent.value
        ) {
          if (this.article.articleTitle.value.trim().length < 4 || this.article.articleTitle.value.trim().length > 120) {
            this.article.articleTitle.error = '文章标题至少4个字符，最多120个字符！'
          } else if (this.article.textContent.value.length < 30 || this.article.textContent.value.length > 326450) {
            this.article.textContent.error = '文章内容至少30个字符，最多326450个字符！'
          } else if (this.article.description.value.length < 12 || this.article.description.value > 120) {
            this.article.description.error = '文章描述至少12个字符，最多120个字符！'
          } else if (this.orgin === 2 && !/https?:\/\/\w+\.\w+\.\w+/.test(this.article.orgin.value)) {
            this.article.orgin.error = '请输入正确的地址！'
          } else {
            this.$emit('table-loading-open', true)

            const orgin = this.orgin === 1 ? 'SELF' : 'LINK'
            const linkURL = this.article.orgin.value

            let $textContent  = null
            let {
              articleTitle,
              description,
              cover,
              type
            } = this.article
            $textContent = document.getElementsByClassName('ql-editor')[0].innerHTML
            type = this.options.filter(item => {
              if (item.type_desc === type.value) {
                return item
              }
            })[0].type_id

            $.ajax({
              type: 'post',
              url: this.bindAPI(`${this.isModify ? 'article/articleModify' : 'article/articlePublish'}`),
              data: {
                articleTitle: articleTitle.value,
                description: description.value,
                cover: cover.value,
                textContent: $textContent,
                type,
                orgin,
                linkURL,
                articleId: this.isModify ? this.$route.query.id : ''
              },
              headers: {
                authorization: this.authorization
              },
              complete: e => {
                const data = JSON.parse(e.responseText)
                const { code, message } = data
                if (code === 200) {
                  this.$router.push('/management/articleList')
                }
                this.$message({
                  type: code === 200 ? 'success' : 'error',
                  message
                })
                this.$emit('table-loading-close', false)
              }
            })
          }
        }
      },
      getArticleOptions() {
        return new Promise((resolve) => {
          $.get(this.bindAPI('article/articleType')).then(res => {
            return resolve(JSON.parse(res).data)
          })
        })
      },
      handleAvatarSuccess(res) {
        this.article.cover.error = ''
        this.article.cover.value = res.data.name
      },
      beforeAvatarUpload (file) {
        const check = !/\.(png|jpg|jpeg)$/.test(file.name)
        if (check) {
          this.$message({
            type: 'error',
            message: '请上传正确的图片！'
          })
        } return !check
      },
      insertCode () {
        if (!this.dialogData.content) {
          this.dialogData.contentError = '代码内容不能为空！'
        } else {
          this.dialogVisible = false
          const { lang, content } = this.dialogData
          this.createCodeWrapper(lang, content)
          this.dialogData.content = ''
          this.dialogData.contentError = null
          this.dialogData.lang = 'JavaScript'
        }
      },
      createCodeWrapper (lang, content) {
        const pre = document.createElement('pre')
        const code = document.createElement('code')
        const wrap = document.createElement('div')
        pre.spellcheck = false
        pre.style.background = '#444'
        code.className = lang.toLowerCase() + ' hljs'
        code.innerHTML = content
        code.style.background = '#000000'
        highLight.highlightBlock(code)
        pre.appendChild(code)
        wrap.appendChild(pre)
        const range = this.quill.getSelection(true);
        this.quill.insertEmbed(range.index, 'code-wrapper', wrap.innerHTML);
      },
      initArticleDetail (id) {
        $.ajax({
          type: 'get',
          url: this.bindAPI(`admin/articleDetail?articleId=${id}`),
          headers: {
            authorization: this.authorization
          },
          complete: e => {
            const result = JSON.parse(e.responseText)
            const { data } = result
            let {
              articleTitle,
              description,
              cover,
              textContent,
              type
            } = this.article
            articleTitle.value = data.articleTitle
            description.value = data.description
            cover.value = data.cover
            type.value = this.options[data.type - 1].type_desc
            textContent.value = data.content
          }
        })
      }
    },
    mounted () {
      this.quill = this.$refs.quill.quill
      const toolbar = this.quill.getModule('toolbar')
      /**
       * @description 插入图片
       */
      toolbar.addHandler('image', () => {
      })
      /**
       * @description 插入代码
       */
      toolbar.addHandler('code', () => {
        this.dialogVisible = true
      })
    },
    created() {
      this.authorization = sessionStorage.getItem('token')
      this.getArticleOptions().then(res => {
        this.options = res
        this.article.type.value = res[0].type_desc
      })
      const { id } = this.$route.query
      this.isModify = id !== undefined
      if (this.isModify) {
        this.initArticleDetail(id)
      }
    }
  }
</script>

<style>
  .avatar-uploader .el-upload {
    border: 1px dashed #d9d9d9;
    border-radius: 6px;
    cursor: pointer;
    position: relative;
    overflow: hidden;
  }
  .avatar-uploader .el-upload:hover {
    border-color: #409EFF;
  }
  .avatar-uploader-icon {
    font-size: 28px;
    color: #8c939d;
    width: 178px;
    height: 178px;
    line-height: 178px !important;
    text-align: center;
  }
  .avatar {
    width: 178px;
    height: 178px;
    display: block;
  }
  .ql-editor {
    min-height: 600px;
  }
</style>
